﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MedicalSystems
{
    public partial class AdvancedFilter : Form
    {
        private Dictionary<string, string> fields;
        private Dictionary<string, int> fieldsIndex;
        private List<Record> filter;
        private DataSourceBuilder dsb;

        public AdvancedFilter()
        {
            InitializeComponent();
            dsb = new DataSourceBuilder();
            fields = new Dictionary<string, string>();
            fields.Add("firstname","FirstName");
            fields.Add("lastname","LastName");
            fields.Add("fullname","FullName");
            fields.Add("parameter","Parameter");
            fields.Add("paramvalue","ParamValue");
            fields.Add("unit","Unit");
            fields.Add("gender", "Gender");
            fields.Add("starttime","startTime");
            fields.Add("finishtime","finishTime");
            fields.Add("txnstarttime","txnStartTime");
            fields.Add("txnfinishtime","txnFinishTime");

            fieldsIndex = new Dictionary<string, int>();
            fieldsIndex.Add("firstname", 0);
            fieldsIndex.Add("lastname", 0);
            fieldsIndex.Add("fullname", 0);
            fieldsIndex.Add("gender", 1);
            fieldsIndex.Add("parameter", 2);
            fieldsIndex.Add("paramvalue", 3);
            fieldsIndex.Add("unit", 4);
            fieldsIndex.Add("starttime", 5);
            fieldsIndex.Add("finishtime", 6);
            fieldsIndex.Add("txnstarttime", 7);
            fieldsIndex.Add("txnfinishtime", 8);

            this.filter = new List<Record>();
            clearFilter();
        }

        private void clearFilter()
        {
            this.grdFilter.DataSource = null;
            initFilters();

            //this.grdFilter = new DataGridView();
            this.grdFilter.DataSource = this.filter;
            this.grdFilter.Refresh();
        }

        private void initFilters()
        {
            this.filter.Clear();
            foreach (Record r in Globals.dataSet)
            {
                this.filter.Add(r);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtQuery.Text = "";
            clearFilter();
        }

        private void btnGo_Click(object sender, EventArgs e)
        {
            string[] query = txtQuery.Text.Split(new char[] { ' ', '\n', '\t' });
            if (query[0].ToUpper() == "SELECT")
            {
                selectFunc(query);
            }
            else if (query[0].ToUpper() == "UPDATE")
            {
                updateFunc(query);
            }
        }

        private void selectFunc(string[] q)
        {
            string param = getSelectQuery(q);
            this.filter = dsb.dynamicList(param);
            grdFilter.DataSource = this.filter;
            grdFilter.Refresh();
        }

        private string getSelectQuery(string[] q)
        {
            string param = "List<MedicalSystems.Record> ans = (from r in Globals.dataSet ";
            for (int i = 1; i < q.Length; i++)
            {
                if (fields.ContainsKey(q[i].ToLower()))
                {
                    param += "r." + fields[q[i].ToLower()] + " ";
                    if (isDateField(q[i].ToLower()))
                    {
                        q[i + 2] = "Convert.ToDateTime(\"" + q[i + 2] + "\")";
                    }
                }
                else
                {
                    param += q[i] + " ";
                }
            }

            param += " select r).ToList();return ans;";
            return param;
        }

        private bool isDateField(string p)
        {
            return p == "starttime" || p == "finishtime" || p == "txnstarttime" || p == "txnfinishtime";
        }

        private void updateFunc(string[] q)
        {
            List<string> tmp = new List<string>();
            tmp.Add("select");
            bool flag = false;
            for (int i = 1; i < q.Length; ++i)
            {
                if (q[i].ToLower() == "where") flag = true;
                if (flag) tmp.Add(q[i].ToLower());
            }
            string selectString = getSelectQuery(tmp.ToArray());
            List<Record> records = dsb.dynamicList(selectString);
            for (int i = 1; i < q.Length && q[i].ToLower() != "where"; ++i)
            {
                if (fields.ContainsKey(q[i].ToLower()))
                {
                    q[i + 2] = q[i + 2].Replace("\"", "");
                    foreach (Record r in records)
                    {
                        r.setValueByIndex(q[i + 2], fieldsIndex[q[i].ToLower()]);
                    }
                }
            }

            this.filter.Clear();
            foreach (Record r in records)
            {
                this.filter.Add(r);
            }
            grdFilter.DataSource = this.filter;
            grdFilter.Refresh();
        }
    }
}
